--[[
Dao Strategy Game (demo for luagame)
Written By: Brett Lajzer

Based on a board game.

This game layout is based on the livecode template.
The main game loop is in main.lua.
--]]


--Set the FPS here (game speed depends on this)
target_fps = 45

--declare things here
board = Object:new()
board.image = get_image("images/gameboard.png")

cursor = Object:new()
cursor.image = get_image("images/cursor.png")
cursor.angular_velocity = 0.25

pieces = {}
pieces[1] = {} pieces[2] = {} pieces[3] = {} pieces[4] = {}
pieces[1][1] = Object:new() pieces[1][1].image = get_image("images/runestone.png") pieces[1][1].owner = "Player 1"
pieces[2][2] = Object:new() pieces[2][2].image = get_image("images/runestone.png") pieces[2][2].owner = "Player 1"
pieces[3][3] = Object:new() pieces[3][3].image = get_image("images/runestone.png") pieces[3][3].owner = "Player 1"
pieces[4][4] = Object:new() pieces[4][4].image = get_image("images/runestone.png") pieces[4][4].owner = "Player 1"

pieces[1][4] = Object:new() pieces[1][4].image = get_image("images/seashell.png") pieces[1][4].owner = "Player 2"
pieces[2][3] = Object:new() pieces[2][3].image = get_image("images/seashell.png") pieces[2][3].owner = "Player 2"
pieces[3][2] = Object:new() pieces[3][2].image = get_image("images/seashell.png") pieces[3][2].owner = "Player 2"
pieces[4][1] = Object:new() pieces[4][1].image = get_image("images/seashell.png") pieces[4][1].owner = "Player 2"

--used for marking valid moves
valid_moves = {}
valid_moves[1] = {} valid_moves[2] = {} valid_moves[3] = {} valid_moves[4] = {}

current_player = "Player 1"
cp_x = 0 cp_y = 0

--super happy fun ending condition graphics!
endlabel = Label:new()
endlabel:set_font("images/VeraBd.ttf",48)
bigrect = Rectangle:new()
bigrect.x = 0 bigrect.y = 0 bigrect.w = 640 bigrect.h = 480 bigrect.r = 0 bigrect.g = 0 bigrect.b = 0 bigrect.a = 128 bigrect.style = "filled"

--clears valid moves
function clear_valid()
  for py=1, 4 do
    for px=1, 4 do
      valid_moves[py][px] = nil
    end
  end
end


--finds moves that are valid
function find_valid(x, y)
  local valid = false
  local mx, my
  
  --check below piece for valid move
  my = y
  while my < 4 do
    if pieces[my+1][x] ~= nil then valid_moves[my][x] = Object:new() valid_moves[my][x].image = get_image("images/valid.png")  valid = true break end
    my = my + 1
  end
  if my == 4 and pieces[4][mx] == nil and valid == false then valid_moves[4][x] = Object:new() valid_moves[4][x].image = get_image("images/valid.png") end
  
  valid = false
  --check above piece for valid move
  my = y
  while my > 1 do
    if pieces[my-1][x] ~= nil then valid_moves[my][x] = Object:new() valid_moves[my][x].image = get_image("images/valid.png")  valid = true break end
    my = my - 1
  end
  if my == 1 and pieces[1][mx] == nil and valid == false then valid_moves[1][x] = Object:new() valid_moves[1][x].image = get_image("images/valid.png") end
 
  valid = false
  --check left of piece for valid move
  mx = x
  while mx > 1 do
    if pieces[y][mx-1] ~= nil then valid_moves[y][mx] = Object:new() valid_moves[y][mx].image = get_image("images/valid.png")  valid = true break end
    mx = mx - 1
  end
  if mx == 1 and pieces[y][1] == nil and valid == false then valid_moves[y][1] = Object:new() valid_moves[y][1].image = get_image("images/valid.png") end

  valid = false
  --check right of piece for valid move
  mx = x
  while mx < 4 do
    if pieces[y][mx+1] ~= nil then valid_moves[y][mx] = Object:new() valid_moves[y][mx].image = get_image("images/valid.png")  valid = true break end
    mx = mx + 1
  end
  if mx == 4 and pieces[y][4] == nil and valid == false then valid_moves[y][4] = Object:new() valid_moves[y][4].image = get_image("images/valid.png") end
 
  valid = false
  --check up and left of piece for valid move
  mx = x
  my = y
  while mx > 1 and my > 1 do
    if pieces[my-1][mx-1] ~= nil then valid_moves[my][mx] = Object:new() valid_moves[my][mx].image = get_image("images/valid.png")  valid = true break end
    mx=mx-1 my=my-1
  end
  if pieces[my][mx] == nil and valid == false then valid_moves[my][mx] = Object:new() valid_moves[my][mx].image = get_image("images/valid.png") end
 
   valid = false
  --check down and right of piece for valid move
  mx = x
  my = y
  while mx < 4 and my < 4 do
    if pieces[my+1][mx+1] ~= nil then valid_moves[my][mx] = Object:new() valid_moves[my][mx].image = get_image("images/valid.png")  valid = true break end
    mx=mx+1 my=my+1
  end
  if pieces[my][mx] == nil and valid == false then valid_moves[my][mx] = Object:new() valid_moves[my][mx].image = get_image("images/valid.png") end
  
   valid = false
  --check down and left of piece for valid move
  mx = x
  my = y
  while mx > 1 and my < 4 do
    if pieces[my+1][mx-1] ~= nil then valid_moves[my][mx] = Object:new() valid_moves[my][mx].image = get_image("images/valid.png")  valid = true break end
    mx=mx-1 my=my+1
  end
  if pieces[my][mx] == nil and valid == false then valid_moves[my][mx] = Object:new() valid_moves[my][mx].image = get_image("images/valid.png") end  
  
   valid = false
  --check up and right of piece for valid move
  mx = x
  my = y
  while mx < 4 and my > 1 do
    if pieces[my-1][mx+1] ~= nil then valid_moves[my][mx] = Object:new() valid_moves[my][mx].image = get_image("images/valid.png")  valid = true break end
    mx=mx+1 my=my-1
  end
  if pieces[my][mx] == nil and valid == false then valid_moves[my][mx] = Object:new() valid_moves[my][mx].image = get_image("images/valid.png") end  
  
  --get rid of valid move over selected piece
  valid_moves[y][x] = nil
  
end


--checks for a winning condition
--returns which player won or nil
function check_win()
  --check corner
  if pieces[1][1] and pieces[4][4] and pieces[4][1] and pieces[1][4] and pieces[1][1].owner == pieces[1][4].owner and pieces[1][4].owner == pieces[4][1].owner and pieces[4][1].owner == pieces[4][4].owner then
    return pieces[1][1].owner
  end
  
  --check rows
  if pieces[1][1] and pieces[1][2] and pieces[1][3] and pieces[1][4] and pieces[1][1].owner == pieces[1][2].owner and pieces[1][2].owner == pieces[1][3].owner and pieces[1][3].owner == pieces[1][4].owner then
    return pieces[1][1].owner
  end
  if pieces[2][1] and pieces[2][2] and pieces[2][3] and pieces[2][4] and pieces[2][1].owner == pieces[2][2].owner and pieces[2][2].owner == pieces[2][3].owner and pieces[2][3].owner == pieces[2][4].owner then
    return pieces[2][1].owner
  end
  if pieces[3][1] and pieces[3][2] and pieces[3][3] and pieces[3][4] and pieces[3][1].owner == pieces[3][2].owner and pieces[3][2].owner == pieces[3][3].owner and pieces[3][3].owner == pieces[3][4].owner then
    return pieces[3][1].owner
  end
  if pieces[4][1] and pieces[4][2] and pieces[4][3] and pieces[4][4] and pieces[4][1].owner == pieces[4][2].owner and pieces[4][2].owner == pieces[4][3].owner and pieces[4][3].owner == pieces[4][4].owner then
    return pieces[4][1].owner
  end
  
  --check columns
  if pieces[1][1] and pieces[2][1] and pieces[3][1] and pieces[4][1] and pieces[1][1].owner == pieces[2][1].owner and pieces[2][1].owner == pieces[3][1].owner and pieces[3][1].owner == pieces[4][1].owner then
    return pieces[1][1].owner
  end
  if pieces[1][2] and pieces[2][2] and pieces[3][2] and pieces[4][2] and pieces[1][2].owner == pieces[2][2].owner and pieces[2][2].owner == pieces[3][2].owner and pieces[3][2].owner == pieces[4][2].owner then
    return pieces[1][2].owner
  end
  if pieces[1][3] and pieces[2][3] and pieces[3][3] and pieces[4][3] and pieces[1][3].owner == pieces[2][3].owner and pieces[2][3].owner == pieces[3][3].owner and pieces[3][3].owner == pieces[4][3].owner then
    return pieces[1][3].owner
  end
  if pieces[1][4] and pieces[2][4] and pieces[3][4] and pieces[4][4] and pieces[1][4].owner == pieces[2][4].owner and pieces[2][4].owner == pieces[3][4].owner and pieces[3][4].owner == pieces[4][4].owner then
    return pieces[1][4].owner
  end
  
  --check for square
  for y=1, 3 do
    for x=1,3 do
      if pieces[y][x] and pieces[y+1][x+1] and pieces[y][x+1] and pieces[y+1][x] then
        if pieces[y][x].owner == pieces[y+1][x].owner and pieces[y+1][x].owner == pieces[y+1][x+1].owner and pieces[y+1][x+1].owner == pieces[y][x+1].owner then
          return pieces[y][x].owner
        end 
      end
    end
  end
    
  return nil
end

--checks for the losing condition
function check_lose()
  if pieces[1][1] and pieces[1][2] and pieces[2][2] and pieces[2][1] then
    if pieces[1][2].owner == pieces[2][2].owner and pieces[2][2].owner == pieces[2][1].owner and pieces[1][1].owner ~= pieces[1][2].owner then
      return pieces[2][2].owner
    end
  end

  if pieces[4][4] and pieces[4][3] and pieces[3][3] and pieces[3][4] then
    if pieces[4][3].owner == pieces[3][4] and pieces[4][3].owner == pieces[3][3].owner and pieces[3][3].owner ~= pieces[4][4].owner then
      return pieces[3][3].owner
    end
  end
  
  if pieces[1][4] and pieces[1][3] and pieces[2][4] and pieces[2][3] then
    if pieces[1][3].owner == pieces[2][3].owner and pieces[2][3].owner == pieces[2][4].owner and pieces[1][4].owner ~= pieces[1][3].owner then
      return pieces[1][3].owner
    end
  end
  
  if pieces[4][1] and pieces[4][2] and pieces[3][1] and pieces[3][2] then
    if pieces[4][2].owner == pieces[3][1].owner and pieces[3][1].owner == pieces[3][2].owner and pieces[4][1].owner ~= pieces[3][1].owner then
      return pieces[4][2].owner
    end
  end
  
  return nil
end

--set up the events here: evman variable
evman.mouse.motion = function(x, y) cursor.x = x cursor.y = y end

--the magic happens here
evman.mouse.released[1] = function(x, y)
  if winner or loser then return end
  
  local xx,yy
  xx = math.ceil(x/120) yy= math.ceil(y/120)
  
  if x < 481 and y < 481 then
    if cp_y ~= 0 and cp_x ~= 0 then
      if valid_moves[yy][xx] ~= nil then
        pieces[yy][xx] = pieces[cp_y][cp_x]
        pieces[cp_y][cp_x] = nil
        clear_valid() cp_y = 0 cp_x = 0
        if current_player == "Player 1" then current_player = "Player 2" else current_player = "Player 1" end
      end
    else
      clear_valid()
      if pieces[yy][xx] ~= nil and pieces[yy][xx].owner == current_player then
        find_valid(xx,yy)
        cp_x = xx cp_y = yy
      end
    end
  else
    cp_y = 0 cp_x = 0
  end
  winner = check_win()
  if winner then
    endlabel:set_caption(winner.." wins!")
    endlabel:update()
    endlabel.x = 320 - math.ceil(endlabel.w/2)
    endlabel.y = 240 - math.ceil(endlabel.h/2)
  end
  loser = check_lose()
  if loser then
    endlabel:set_caption(loser.." loses!")
    endlabel:update()
    endlabel.x = 320 - math.ceil(endlabel.w/2)
    endlabel.y = 240 - math.ceil(endlabel.h/2)
  end
end

--reset stuff when you right-click
evman.mouse.pressed[3] = function()
  clear_valid() cp_x = 0 cp_y = 0
end

--happy fun labels for indicating which player's turn it is
p1label = Label:new()
p1label:set_font("images/VeraBd.ttf", 20)
p1label:set_caption("Player 1")
p1label:update()
p1label.x = 480 + math.ceil((160-p1label.w)/2)
p1label.y = 10
p1image = Object:new()
p1image.image = get_image("images/runestone.png")
p1image.y = p1label.h + p1label.y + 10
p1image.x = 500

p2label = Label:new()
p2label:set_font("images/VeraBd.ttf", 20)
p2label:set_caption("Player 2")
p2label:update()
p2label.x = 480 + math.ceil(p2label.w/2)
p2label.y = 10
p2image = Object:new()
p2image.image = get_image("images/seashell.png")
p2image.y = p2label.h + p2label.y + 10
p2image.x = 500



--updating stuff goes here
function global_update()
  cursor:update()
end


--drawing stuff goes here
function global_draw()
  board:draw()
  --nested for loop to draw pieces and valid overlay...
  for py=1, 4 do
    for px=1, 4 do
      if pieces[py][px] ~= nil then
        pieces[py][px].y = (py - 1) * 120
        pieces[py][px].x = (px - 1) * 120        
        pieces[py][px]:draw()
      end
      if valid_moves[py][px] ~= nil then
        valid_moves[py][px].y = (py - 1) * 120
        valid_moves[py][px].x = (px - 1) * 120        
        valid_moves[py][px]:draw()
      end
    end
  end

  
  --draw which player's turn it is
  if current_player == "Player 1" then
    p1label:draw()
    p1image:draw()
  else
    p2label:draw()
    p2image:draw()  
  end
  
  if winner then
    bigrect:draw()
    endlabel:draw()
  end
  if loser then
    bigrect:draw()
    endlabel:draw()
  end
    
  cursor:draw()
end


--collision stuff goes here
function global_collide()

end
